package mybatis.config;

import mybatis.mapper.MapperStatement;
import mybatis.utils.XmlUtils;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author cg
 * @date 2023/6/20 13:38
 * 配置相关
 */
public class Configuration {
    //配置文件
    private static final Properties properties = new Properties();

    //id与mapper的对应关系，id为全类名+方法名
    private final Map<String, MapperStatement> mapperStatementMap = new ConcurrentHashMap<>();

    public Configuration(String path) {
        try {
            //加载配置类信息
            properties.load(this.getClass().getClassLoader().getResourceAsStream(path));
            this.load();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //初始化解析所有的mapper信息
    private void load() {
        String location = properties.getProperty("mapper.location").replaceAll("\\.", "/");
        String realPath = this.getClass().getResource("/").getPath() + location;
        File rootDir = new File(realPath);
        if (rootDir.exists()) {
            //解析并注册所有的xml文件
            doRegist(rootDir);
        }
    }

    private void doRegist(File rootDir) {
        for (File file : rootDir.listFiles()) {
            String fileName = file.getName();
            if (file.isFile()) {
                //解析xml文件
                if (fileName.endsWith(".xml")){
                    //解析xml文件名注册到mapperStatementMap中
                    XmlUtils.readMapperXml(file, this);
                }
            }else {
                doRegist(file);
            }
        }
    }

    //注册所有解析后的mapper信息
    public void registMapperStatement(String sqlId, MapperStatement mapperStatement) {
        mapperStatementMap.put(sqlId, mapperStatement);
    }
    public MapperStatement getMapperStatement(String sqlId) {
        return mapperStatementMap.get(sqlId);
    }

    public static Properties getProperties() {
        return properties;
    }
}
